﻿using System;
using dIRca.Data.Settings;
using NLog;
#if (WINDOWS_PHONE)
using Homebrew.Net.Sockets;
#else
using System.Net.Sockets;
#endif

namespace dIRca.Network
{
    class ConnectionService : IDisposable
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
        private TcpClient _tcpClient = null;
        public NetworkStream Stream { get; private set; }

        public bool IsConnected { get; private set; }

        public string SendBuffer { get; set; }
        public string ReceiveBuffer { get; set; }

        private Server _server;
        private int _defaultPort;

        public event EventHandler Connecting;
        public event EventHandler Connected;
        public event EventHandler Disconnected;

        public ConnectionService(Server server, int defaultPort)
        {
            _server = server;
            _defaultPort = defaultPort;
        }

        public void OnConnecting()
        {
            var handler = Connecting;
            if (handler != null)
            {
                var eventArgs = new EventArgs();
                handler(this, eventArgs);
            }
        }

        public void OnConnected()
        {
            var handler = Connected;
            if (handler != null)
            {
                var eventArgs = new EventArgs();
                handler(this, eventArgs);
            }
        }

        public void OnDisconnected()
        {
            var handler = Disconnected;
            if (handler != null)
            {
                var eventArgs = new EventArgs();
                handler(this, eventArgs);
            }
        }

        public void Shutdown()
        {
            Dispose();
        }

        public void Connect()
        {
            if (!IsConnected)
            {
                try
                {
                    if (!string.IsNullOrEmpty(_server.HostName))
                    {
                        var hostName = _server.HostName;
                        var port = _server.Port;
                        if (port <= 0)
                        {
                            port = _defaultPort;
                        }
                        if (!string.IsNullOrEmpty(hostName))
                        {
                            _tcpClient = new TcpClient();
                            OnConnecting();
                            _tcpClient.Connect(hostName, port);
                            // TODO: Logging the Connection events
                        }
                    }
                }
                catch (Exception)
                {
                }

                if ((_tcpClient.Client != null) && (_tcpClient.Client.Connected))
                {
                    Stream = _tcpClient.GetStream();
                    IsConnected = true;
                    OnConnected();
                }
                else
                {
                    IsConnected = false;
                    OnDisconnected();
                }
            }
        }

        public void Disconnect(bool reuseSocket)
        {
            if (_tcpClient.Client != null) 
                _tcpClient.Client.Disconnect(reuseSocket);
            IsConnected = false;
            OnDisconnected();
            if (!reuseSocket)
                Close();
        }

        void Close()
        {
            _tcpClient.Close();
        }

        public void Dispose()
        {
            Close();
            _tcpClient.Client.Dispose();
            _tcpClient = null;
        }
    }
}
